Skip to content

Conversation

@Roushelfy
Copy link
Contributor

This PR introduces two major improvements to the IPC coupling system:

  1. Simplified rigid body mesh handling

    • Use uipc.geometry.trimesh directly instead of converting to tetmesh
    • ABD works with surface meshes, no need for volumetric tetmesh
    • Improves performance and simplifies mesh processing pipeline
  2. IPC-only rigid bodies (one-way coupling)

    • Add set_link_only_in_ipc(entity) API for entities that only exist in IPC
    • These entities use full density (no mass splitting with Genesis)
    • Skip SoftTransformConstraint (no coupling forces)
    • Directly set Genesis transforms from IPC results
    • Fix quaternion conversion: scipy [x,y,z,w] -> Genesis [w,x,y,z]
    • Zero velocities after transform updates to avoid spurious forces
    • Useful for passive rigid objects like screws, nuts that only need accurate contact

Usage:
scene.sim.coupler.set_link_only_in_ipc(entity=screw)

This PR introduces two major improvements to the IPC coupling system:

1. Simplified rigid body mesh handling
   - Use uipc.geometry.trimesh directly instead of converting to tetmesh
   - ABD works with surface meshes, no need for volumetric tetmesh
   - Improves performance and simplifies mesh processing pipeline

2. IPC-only rigid bodies (one-way coupling)
   - Add set_link_only_in_ipc(entity) API for entities that only exist in IPC
   - These entities use full density (no mass splitting with Genesis)
   - Skip SoftTransformConstraint (no coupling forces)
   - Directly set Genesis transforms from IPC results
   - Fix quaternion conversion: scipy [x,y,z,w] -> Genesis [w,x,y,z]
   - Zero velocities after transform updates to avoid spurious forces
   - Useful for passive rigid objects like screws, nuts that only need accurate contact

Usage:
    scene.sim.coupler.set_link_only_in_ipc(entity=screw)
Replace set_ipc_link_filter() and set_link_only_in_ipc() with a single
set_link_ipc_coupling_type() API that supports three coupling modes:

- 'both': Two-way coupling (IPC <-> Genesis, default behavior)
- 'ipc_only': One-way coupling (IPC -> Genesis, now supports non-base links)
- 'genesis_only': Exclude links from IPC entirely

Key improvements:
- Unified interface for all coupling configurations
- Per-link coupling control via link_names/link_indices
- Support non-base links in ipc_only mode
- Better flexibility for mixed coupling scenarios
- Update examples to use new API
YilingQiao
YilingQiao previously approved these changes Nov 13, 2025
YilingQiao
YilingQiao previously approved these changes Nov 17, 2025
@YilingQiao YilingQiao enabled auto-merge (squash) November 17, 2025 01:59
@duburcqa duburcqa disabled auto-merge November 17, 2025 08:03
if self.options.two_way_coupling:
self._apply_abd_coupling_forces(abd_data_by_link)

def _set_genesis_transforms_from_ipc(self, abd_data_by_link):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is very inefficient and should be improved before merging. Please implement a dedicated taichi kernel for this.

Copy link
Collaborator

@duburcqa duburcqa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must improve performance

@duburcqa
Copy link
Collaborator

Moreover, unit tests should be implemented, with skip if module is not available.

- Add coupling_strategy option (two_way_soft_constraint, contact_proxy)
- Move _genesis_stored_states from rigid_solver to ipc_coupler
- Implement _record_ipc_contact_forces() to extract contact forces from IPC
- Implement _apply_ipc_contact_forces() to apply forces to Genesis links
- Refactor _set_genesis_transforms_from_ipc() to support multi-link IK
  - Use inverse_kinematics_multilink for complex entities
  - Direct base link setting for simple single-body entities
- Add strategy-based dispatching in substep_pre/post_coupling
- Add 6 new Taichi kernels for parallel computation:
  * _compute_external_wrench_kernel: 12D wrench calculation
  * _compute_coupling_forces_kernel: ABD coupling forces
  * _compute_link_contact_forces_kernel: contact force accumulation
  * _batch_read_qpos_kernel: batch qpos reading
  * _compare_qpos_kernel: parallel qpos comparison
  * _batch_pos_quat_to_transform_kernel: batch transform conversion

- Pre-allocate Taichi fields to reduce memory allocation overhead
- Optimize _compute_link_contact_forces_and_torques with kernel-driven approach
- Optimize _apply_ipc_contact_forces with batching
- Optimize _store_genesis_rigid_states with batch qpos reading
- Optimize _set_genesis_transforms_from_ipc with kernel comparison

Performance improvements: 10-100x speedup for contact-heavy scenarios
Resolved conflicts:
- genesis/engine/solvers/rigid/rigid_solver_decomp.py
  * Updated substep() calls to include 'f' parameter (from origin/main)
  * Kept IPC coupling strategy dispatch logic (from HEAD)
  * Combined both changes for proper IPC two_way_soft_constraint support
- Check if scene is parallelized before passing envs_idx parameter
- Fixes GenesisException: 'envs_idx is not supported for non-parallelized scene'
- Ensures compatibility with both parallelized and non-parallelized scenarios
- IPC contact gradients are force * dt^2, not force
- Divide by dt^2 when accumulating contact forces
- Use self.options.dt (IPC dt) instead of sim dt
- Add IPCTransformData and IPCCouplingData classes following Genesis pattern
- Pre-allocate all arrays as Taichi fields, eliminate runtime allocations
- Refactor _set_genesis_transforms_from_ipc with parallel kernel processing
- Add initialization and filtering kernels for parallel processing
- Rename _compute_external_wrench_kernel to _compute_external_force_kernel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants